import wx
import os
import MainAppHandler

class imageFile():
   # One of my thoughts was to have two objects. The original object
   # And then a temporary copy that has the current size, but I think
   # the memory usage would be too great. Sooo... evey time the image
   # resizes, etc, it needs to grab the image from disk.
   
   # Another idea I have:
   #  I could use the orig object and the the working copy but then
   # have some kind of limit, either by memory usage (if I have access to thaat)
   # or by number of files kept in memory (more probable). That way I could
   # then free files as they are not used but still keep the performace gain
   # of having these copies around. I would probably need to use some kind of
   # multi-threaded task that would show the image and then queue up additional
   # images in the background

   def __init__(self,iName=None):
      self.Name = iName
      self.Object = None
   def __del__(self):
      del self.Object

class FileHandler():

   def __init__(self,mainAppHandler):
      wx.InitAllImageHandlers()
      self._mainHandler = mainAppHandler
      self._handlers = {
            "OPEN"     : self.open,
            "CLOSE"    : self.close,
            "CLOSEALL" : self.closeall,
            "EXIT"     : self.exit,
            "SAVEALL"  : self.saveall,
            "PREVIOUS" : self.previous,
            "NEXT"     : self.next
      }
      self._files = []
      self._curFile = None

   def handler(self,tag,event):
      # Call the correct handler
      self._handlers[tag[0]]()

   def open(self):
      # TODO: make it customize:
      #     default dir
      #     support translations
      types = "Supported image files (BMP, GIF, PNG, JPEG)|*.bmp;*.gif;*.png;*.jpg|All files|*.*"
      dialog = wx.FileDialog(
            self._mainHandler.getHandle("MAINWINDOW"),
            message="Please choose a file",
            defaultDir=os.getcwd(),
            defaultFile="",
            style=wx.OPEN|wx.MULTIPLE|wx.CHANGE_DIR,
            wildcard=types
      )

      if dialog.ShowModal() == wx.ID_OK:
         paths = dialog.GetPaths()
         for path in paths:
            self._files.append(imageFile(path))
         if self._curFile is None:
            self._curFile = 0
         self._mainHandler.canvasHandler.Draw()
         self._updateButtons()

   # defaults to closing current file
   def close(self,fileNum = None):
      if fileNum is None:
         fileNum = self._curFile
      
      del(self._files[fileNum])

      # If we just deleted the last file, make sure to decrement curFile
      if self._curFile is len(self._files):
         self._curFile -= 1

      # If the file list is now empty, reset curFile
      if len(self._files) is 0:
         self._curFile = None

      self._mainHandler.canvasHandler.Draw()
      self._updateButtons()

   def closeall(self):
      # Nuke and recreate the file list
      del(self._files)
      self._files = {}

      # Reset curFile
      self._curFile = None

      self._mainHandler.canvasHandler.Draw()
      self._updateButtons()


   def exit(self):
      quit()
      return

   def saveall(self):
      return

   # Note: previous and next don't do checking!
   # It is assumed that and that they won't be called if it would cause something
   # invalid. That is the job of _updateButtons
   def previous(self):
      self._curFile -= 1
      self._mainHandler.canvasHandler.Draw()
      self._updateButtons()

   def next(self):
      self._curFile += 1
      self._mainHandler.canvasHandler.Draw()
      self._updateButtons()

   def _updateButtons(self):
        nextButtons = [
              self._mainHandler.getHandle("FILE_NEXT"),
              self._mainHandler.getHandle("TOOLS_NEXTFILE")
            ]
        prevButtons = [
              self._mainHandler.getHandle("FILE_PREVIOUS"),
              self._mainHandler.getHandle("TOOLS_PREVIOUSFILE")
            ]

        prevVal = self._curFile > 0
        nextVal = self._curFile < (len(self._files) - 1)

        for b in nextButtons:
           b.Enable(nextVal)

        for b in prevButtons:
           b.Enable(prevVal)

   # Returns a link to an image object
   # Images are created / rendered as needed. That way you can load 1,000 images
   # instantly, and only will take time to render as each
   #  one is displayed.
   def _getFile(self, fileNumber):
      if type(fileNumber) is not int or fileNumber < 0:
         image_object = None #Invalid file number
      elif self._files[fileNumber] is not None:
         image_object = self._files[fileNumber].Object
         if image_object is None:
            # Image has not been created
            fileName = self._files[fileNumber].Name
            tmp_object = wx.Image(fileName).ConvertToBitmap()
            image_object = {
                  "object" : tmp_object,
                  "width"  : tmp_object.GetWidth(),
                  "height" : tmp_object.GetHeight()
               }
            self._files[fileNumber].Object = image_object

      return image_object

   # Returns a link object to the currently viewed image
   # or returns None if no image is currently open
   def getCurFile(self):
      return self._getFile(self._curFile)
